#include "tcpSocket.h"

TcpSocket::TcpSocket()
{
    this->_sockfd = -1;
}

bool TcpSocket::Socket()
{
    this->_sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (_sockfd < 0)
    {
        perror("socket error");
        return false;
    }
    return true;
}

bool TcpSocket::Bind(const std::string &ip, uint16_t port)
{
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(ip.c_str());
    socklen_t len = sizeof(struct sockaddr_in);
    
    int ret = bind(this->_sockfd, (struct sockaddr*)&addr, len);
    if (ret < 0)
    {
        perror("bind error");
        return false;
    }
    return true;
}

bool TcpSocket::Listen(int backlog)
{
    int ret = listen(this->_sockfd, backlog);
    if (ret < 0)
    {
        perror("listen error");
        return false;
    }
    return true;
}

bool TcpSocket::Accept(TcpSocket *new_sock, std::string *ip, uint16_t *port)
{
    struct sockaddr_in addr;
    socklen_t len = sizeof(struct sockaddr_in);
    int new_fd = accept(this->_sockfd, (struct sockaddr*)&addr, &len);
    std::cout << "dsdsdds";
    if (new_fd < 0)
    {
        perror("accept error");
        return false;
    }
    new_sock->_sockfd = new_fd;
    if (ip != NULL)
    {
        *ip = inet_ntoa(addr.sin_addr);
    }
    if (port != NULL)
    {
        *port = ntohs(addr.sin_port);
    }
    return true;
}

bool TcpSocket::Recv(std::string *buf, int flag)
{
    char tmp[4096] = {0};
    int ret = recv(this->_sockfd, tmp, 4096, flag);
    if (ret < 0)
    {
        perror("recv error");
        return false;
    }
    else if (ret == 0)//默认阻塞，没有数据就会等待，返回0表示连接断开
    {
        printf("connection broken\n");
        return false;
    }
    buf->assign(tmp, ret);
    return true;
}

bool TcpSocket::Send(const std::string &data)
{
    int ret = send(this->_sockfd, data.c_str(), data.size(), 0);
    if (ret < 0)
    {
        perror("send error");
        return false;
    }
    return true;
}

bool TcpSocket::Close()
{
    if (this->_sockfd > 0)
    {
        close(_sockfd);
        _sockfd = -1;
    }
    return true;
}

bool TcpSocket::Connect(const std::string &ip, uint16_t port)
{
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(ip.c_str());
    socklen_t len = sizeof(struct sockaddr_in);
    int ret = connect(this->_sockfd, (struct sockaddr*)&addr, len);
    if (ret < 0)
    {
        perror("connect error");
        return false;
    }
    return true;
}
